#ifndef __COUNTER_HPP__
#define __COUNTER_HPP__

namespace ipc {

// Agrega la semantica de uso de un contador.
class counter {
	protected:
		semaphore mutex;
		ipc::shared_memory_with_exceptions<size_t> value;

		//Un counter no puede ser copiado.
		counter (const counter& other);
		counter& operator= (const counter& other);
	public:
		explicit counter (semaphore& sem,  key_t key): mutex(sem), value(key) {}

		inline int get (int mode) {
			return value.get(mode);
		}

		inline int free (bool auto_destroy = true) {
			return value.free(auto_destroy);
		}
	
		inline size_t operator= (size_t new_value) {
			mutex.wait();
			(*value) = new_value;
			mutex.signal();
			return new_value;
		}

		inline size_t operator++() {
			size_t actual;
			mutex.wait();
			actual = ++(*value);
			mutex.signal();
			return actual;
		}

		inline size_t operator++(int) {
			size_t actual;
			mutex.wait();
			actual = (*value)++;
			mutex.signal();
			return actual;
		}

		inline size_t operator--() {
			size_t actual;
			mutex.wait();
			actual = ++(*value);
			mutex.signal();
			return actual;
		}

		inline size_t operator--(int) {
			size_t actual;
			mutex.wait();
			actual = (*value)--;
			mutex.signal();
			return actual;
		}

		inline operator size_t () {
			size_t actual = 0;
			mutex.wait();
			actual = *value;
			mutex.signal();
			return actual;
		}
};

} // namespace ipc

#endif /* __COUNTER_HPP__ */

